﻿using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;

namespace ProjScan.Submodules.Effects_Play_Check
{
    internal static class GameViewSizeManager
    {
        public enum GameViewSizeType
        {
            AspectRatio,
            FixedResolution
        }

        private static object gameViewSizesInstance;

        private static MethodInfo getGroupMethod;

        static GameViewSizeManager()
        {
            Type type = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes");
            Type[] typeArguments = new Type[1]
            {
                type
            };
            PropertyInfo property = typeof(ScriptableSingleton<>).MakeGenericType(typeArguments).GetProperty("instance");
            getGroupMethod = type.GetMethod("GetGroup");
            gameViewSizesInstance = property.GetValue(null, null);
        }

        public static void SetResolution(int width, int height, string sizeLabel)
        {
            if (GetResolutionIndex(GetCurrentGroupType(), width, height) == -1)
            {
                AddGameViewSize(GameViewSizeType.FixedResolution, GetCurrentGroupType(), width, height, sizeLabel);
            }

            SetSelectedSizeIndex(GetResolutionIndex(GetCurrentGroupType(), width, height));
        }

        public static void SetSelectedSizeIndex(int sizeIndex)
        {
            Type type = typeof(Editor).Assembly.GetType("UnityEditor.GameView");
            PropertyInfo property = type.GetProperty("selectedSizeIndex", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
            EditorWindow window = EditorWindow.GetWindow(type);
            property.SetValue(window, sizeIndex, null);
        }

        public static void AddGameViewSize(GameViewSizeType sizeType, GameViewSizeGroupType groupType, int width, int height, string sizeLabel)
        {
            object group = GetGroup(groupType);
            MethodInfo method = getGroupMethod.ReturnType.GetMethod("AddCustomSize");
            Type type = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSize");
            Type[] types = new Type[4]
            {
                typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType"),
                typeof(int),
                typeof(int),
                typeof(string)
            };
            object[] parameters = new object[4]
            {
                (int)sizeType,
                width,
                height,
                sizeLabel
            };
            object obj = type.GetConstructor(types).Invoke(parameters);
            object[] parameters2 = new object[1]
            {
                obj
            };
            method.Invoke(group, parameters2);
        }

        public static bool HasSizeType(GameViewSizeGroupType gameViewSizeGroupType, string sizeLabel)
        {
            return GetSizeTypeIndex(gameViewSizeGroupType, sizeLabel) != -1;
        }

        public static int GetSizeTypeIndex(GameViewSizeGroupType gameViewSizeGroupType, string sizeLabel)
        {
            object group = GetGroup(gameViewSizeGroupType);
            string[] array = group.GetType().GetMethod("GetDisplayTexts").Invoke(group, null) as string[];
            for (int i = 0; i < array.Length; i++)
            {
                string text = array[i];
                int num = text.IndexOf('(');
                if (num != -1)
                {
                    text = text.Substring(0, num - 1);
                }

                if (text == sizeLabel)
                {
                    return i;
                }
            }

            return -1;
        }

        public static bool IsGameViewSizeExists(GameViewSizeGroupType gameViewSizeGroupType0, int width, int height)
        {
            return GetResolutionIndex(gameViewSizeGroupType0, width, height) != -1;
        }

        public static int GetResolutionIndex(GameViewSizeGroupType gameViewGroupType, int width, int height)
        {
            object group = GetGroup(gameViewGroupType);
            Type type = group.GetType();
            MethodInfo method = type.GetMethod("GetBuiltinCount");
            MethodInfo method2 = type.GetMethod("GetCustomCount");
            int num = (int)method.Invoke(group, null) + (int)method2.Invoke(group, null);
            MethodInfo method3 = type.GetMethod("GetGameViewSize");
            Type returnType = method3.ReturnType;
            PropertyInfo property = returnType.GetProperty("width");
            PropertyInfo property2 = returnType.GetProperty("height");
            object[] array = new object[1];
            for (int i = 0; i < num; i++)
            {
                array[0] = i;
                object obj = method3.Invoke(group, array);
                int num2 = (int)property.GetValue(obj, null);
                int num3 = (int)property2.GetValue(obj, null);
                if (num2 == width && num3 == height)
                {
                    return i;
                }
            }

            return -1;
        }

        private static object GetGroup(GameViewSizeGroupType gameViewSizeGroupType)
        {
            object[] parameters = new object[1]
            {
                (int)gameViewSizeGroupType
            };
            return getGroupMethod.Invoke(gameViewSizesInstance, parameters);
        }

        public static GameViewSizeGroupType GetCurrentGroupType()
        {
            return (GameViewSizeGroupType)(int)gameViewSizesInstance.GetType().GetProperty("currentGroupType").GetValue(gameViewSizesInstance, null);
        }

        public static void AdjustScreenResolution()
        {
            int height = Screen.height;
            int width = Screen.width;
            int resolutionIndex = GetResolutionIndex(GetCurrentGroupType(), height, width);
            if (resolutionIndex == -1)
            {
                AddGameViewSize(GameViewSizeType.FixedResolution, GetCurrentGroupType(), height, width, "");
                resolutionIndex = GetResolutionIndex(GetCurrentGroupType(), height, width);
            }

            if (resolutionIndex != -1)
            {
                SetSelectedSizeIndex(resolutionIndex);
            }
            else
            {
                Debug.LogError($"switchOrientation failed, can not find or add resolution for {height}*{width}");
            }
        }
    }
}